package com.ruoyi.common.utils;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.web.client.ResponseExtractor;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

@Slf4j
public class RestTemplateClient {

    public static RestTemplate getRestTemplate() {
        return SpringUtils.getBean(RestTemplate.class);
    }

    /**
     * 发送POST请求
     *
     * @param url          请求URL
     * @param headers      请求头
     * @param requestBody  请求体
     * @param responseType 响应类型
     * @return 响应结果
     */
    public static <T> ResponseEntity<T> post(String url, Map<String, String> headers,
                                             Object requestBody, Class<T> responseType) {
        HttpHeaders httpHeaders = new HttpHeaders();

        // 设置请求头
        if (headers != null) {
            headers.forEach(httpHeaders::set);
        }

        // 如果请求体是字符串，设置Content-Type为application/json
        if (requestBody instanceof String) {
            httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        }

        HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody, httpHeaders);

        try {
            return getRestTemplate().exchange(url, HttpMethod.POST, requestEntity, responseType);
        } catch (RestClientException e) {
            throw new RuntimeException("请求失败: " + e.getMessage(), e);
        }
    }

    /**
     * 发送POST请求
     *
     * @param url               请求URL
     * @param headers           请求头
     * @param requestBody       请求体
     * @param responseExtractor 响应类型
     */
    public static <T> void post(String url, Map<String, String> headers,
                                Object requestBody, ResponseExtractor<T> responseExtractor) {
        HttpHeaders httpHeaders = new HttpHeaders();

        // 设置请求头
        if (headers != null) {
            headers.forEach(httpHeaders::set);
        }

        // 如果请求体是字符串，设置Content-Type为application/json


        HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody, httpHeaders);

        try {
            getRestTemplate().execute(url,
                    HttpMethod.POST,
                    request -> {
                        // 设置请求头和请求体
                        request.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                        request.getHeaders().addAll(requestEntity.getHeaders());
                        // 写入请求体
                        if (requestEntity.getBody() != null) {
                            request.getBody().write(requestEntity.getBody().toString().getBytes());
                            request.getBody().flush();
                        }
                        log.debug(JSONObject.toJSONString(request));
                    },
                    responseExtractor
            );
        } catch (RestClientException e) {
            throw new RuntimeException("请求失败: " + e.getMessage(), e);
        }
    }

    /**
     * 发送POST请求（返回字符串）
     *
     * @param url         请求URL
     * @param headers     请求头
     * @param requestBody 请求体
     * @return 响应字符串
     */
    public static ResponseEntity<String> post(String url, Map<String, String> headers, Object requestBody) {
        return post(url, headers, requestBody, String.class);
    }

    /**
     * 发送GET请求
     *
     * @param url          请求URL
     * @param headers      请求头
     * @param responseType 响应类型
     * @return 响应结果
     */
    public static <T> ResponseEntity<T> get(String url, Map<String, String> headers, Class<T> responseType) {
        HttpHeaders httpHeaders = new HttpHeaders();

        // 设置请求头
        if (headers != null) {
            headers.forEach(httpHeaders::set);
        }

        HttpEntity<Object> requestEntity = new HttpEntity<>(httpHeaders);

        try {
            return getRestTemplate().exchange(url, HttpMethod.GET, requestEntity, responseType);
        } catch (RestClientException e) {
            throw new RuntimeException("请求失败: " + e.getMessage(), e);
        }
    }

    /**
     * 发送GET请求（返回字符串）
     *
     * @param url     请求URL
     * @param headers 请求头
     * @return 响应字符串
     */
    public static ResponseEntity<String> get(String url, Map<String, String> headers) {
        return get(url, headers, String.class);
    }

    /**
     * 发送PUT请求
     *
     * @param url          请求URL
     * @param headers      请求头
     * @param requestBody  请求体
     * @param responseType 响应类型
     * @return 响应结果
     */
    public static <T> ResponseEntity<T> put(String url, Map<String, String> headers,
                                            Object requestBody, Class<T> responseType) {
        HttpHeaders httpHeaders = new HttpHeaders();

        // 设置请求头
        if (headers != null) {
            headers.forEach(httpHeaders::set);
        }

        // 如果请求体是字符串，设置Content-Type为application/json
        if (requestBody instanceof String) {
            httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        }

        HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody, httpHeaders);

        try {
            return getRestTemplate().exchange(url, HttpMethod.PUT, requestEntity, responseType);
        } catch (RestClientException e) {
            throw new RuntimeException("请求失败: " + e.getMessage(), e);
        }
    }

    /**
     * 发送DELETE请求
     *
     * @param url          请求URL
     * @param headers      请求头
     * @param responseType 响应类型
     * @return 响应结果
     */
    public static <T> ResponseEntity<T> delete(String url, Object requestBody, Map<String, String> headers, Class<T> responseType) {
        HttpHeaders httpHeaders = new HttpHeaders();

        // 设置请求头
        if (headers != null) {
            headers.forEach(httpHeaders::set);
        }
        // 如果请求体是字符串，设置Content-Type为application/json
        if (requestBody instanceof String) {
            httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        }

        HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody, httpHeaders);

        try {
            return getRestTemplate().exchange(url, HttpMethod.DELETE, requestEntity, responseType);
        } catch (RestClientException e) {
            throw new RuntimeException("请求失败: " + e.getMessage(), e);
        }
    }
}
